package com.aSemy.qotwReader.core.parseInput;

import com.aSemy.qotwReader.core.types.*;

/**
 * The commands given to this program to set variables needed for conversion and downloading.
 * @author Adam Semenenko
 */
public enum Command 
{
    download(DownloadAction.values(), "Which question(s) should be downloaded."),
    output(EbookType.values(), "The ebook format the question should be saved as.\n Epub works quite well."),
    reader(ReaderType.values(), "The ebook reader that the ebooks should be tailored for.\n Defaultreader should be fine if you're unsure."),
    calibredir("\"C:\\Program Files\\Calibre2\".", "The directory in which Calibre has been installed."),
    ;
    
    /** The string that a command starts with. */
    private static final String commandDesignator = "-";
    
    /** Enumerators that are valid arguments for a command. */
    final private ArgumentOfCommand[] validArgs;
    /** A description of the command. */
    final private String description;
    /** An example argument for the command. */
    final private String exampleArg;
    
    /**
     * Creates a new command.
     * @param validArgs Enumerators that can be used as arguments 
     * @param desciption What the command is for and the argument that it takes.
     */
    private Command(ArgumentOfCommand[] validArgs, String desciption)
    {
        this.validArgs = validArgs;
        this.description = desciption;
        this.exampleArg = validArgs[0].toString();
    }
    
    /**
     * Creates a new command
     * @param exampleArg An example of an argument that the command takes
     * @param description What the command is for and the argument that it takes.
     */
    private Command(String exampleArg, String description)
    {
        validArgs = null;
        this.description = description;
        this.exampleArg = exampleArg;
    }
    
    /**
     * Get a description of the command.
     * @return A string of the description.
     */
    public String getDescription() { return this.description; }
    /**
     * When the command is used in the command line this is what it should equal.
     * It's the name of the command prepended with the {@link #commandDesignator}.
     * 
     * @return The command in a string that should be used in the command line 
     */
    public String getCommandString() { return commandDesignator + this.toString(); }
    
    /**
     * A command can only take specified strings as arguments.
     * <br>
     * If the command uses enumerators as an argument then this is an array of all
     * valid enumerator (as listed in {@link #validArgs}) names.
     * <br>
     * Otherwise the example command in {{@link #exampleArg} is returned (as an array of one element).
     * 
     * @return A list of valid strings that can be used as an argument for this command.
     */
    public String[] getValidArgs()
    {   
        if (validArgs == null)
        {
            String[] exampleArgInArray = { exampleArg };
            return exampleArgInArray;
        }
        else
        {
            String[] argStrings = new String[validArgs.length];
            for (int i = 0; i < validArgs.length; i++)
                argStrings[i] = validArgs[i].toString();
            return argStrings;
        }
    }
    
    /**
     * Gets an array of strings listing valid commands for this command. 
     * @return
     */
    public static String getAvailCmdsString()
    {
        String availCmds = "";
        for (Command c : Command.values())
            availCmds += c.getCommandString() + "   ";
        return availCmds;
    }
    
    /**
     * A command has a list of commands which are valid. This method returns them in a single String which is easy to print.
     * @return A space-separated string for all valid arguments for this command.
     */
    public String getValidArgsString()
    {
        String validArgs = "";
        for (String s : getValidArgs())
            validArgs += s + "  ";
        
        return validArgs;
    }
}